﻿using System;
using System.Collections.Generic;
using System.Text;
using taxi_sovereign.interfaces;

namespace taxi_sovereign.model
{
    [Serializable]
    class Road:IRoad
    {
        private string name;
        private bool chosen = false;
        private bool chosenchosen = false;
        private float Length;
        private float SpeedModifier;
        private float DurabilityDecreaseModifier;
        private float FuelDecreaseModifier;
        private float directionX;
        private float directionY;
        private ICross Cross1;
        private ICross Cross2;
        private IStop[] Stops = new IStop[0];
        private IVehicle[] Vehicles = new IVehicle[0];

        public Road(ICross C1, ICross C2, string name)
        {
            Cross1 = C1;
            Cross2 = C2;
            Name = name;
            Length = (float)Math.Sqrt((Cross1.GetPositionX() - Cross2.GetPositionX()) *
                                (Cross1.GetPositionX() - Cross2.GetPositionX()) +
                                (Cross1.GetPositionY() - Cross2.GetPositionY()) *
                                (Cross1.GetPositionY() - Cross2.GetPositionY()));
            
            C1.AddRoad(this);
            C2.AddRoad(this);
            directionX = (C2.GetPositionX() - C1.GetPositionX()) / Length;
            directionY = (C2.GetPositionY() - C1.GetPositionY()) / Length;
            SpeedModifier = _Constants._roadspeedmodifier;
            DurabilityDecreaseModifier = _Constants._roaddurabilitydecreasemodifier;
            FuelDecreaseModifier = _Constants._roadfueldecreasemodifier;
            
        }

        public void AddStop(IStop inputstop)
        {
            Array.Resize(ref Stops, Stops.Length + 1);
            Stops[Stops.Length - 1] = inputstop;
            
        }

        public void DelStop(IStop inputstop)
        {
            int k = -1;
            for (int i = 0; i < Stops.Length; i++)
            {
                if (inputstop == Stops[i])
                {
                    k = i; 
                }
            }
            if (k != -1) 
            for (int i = k; i < Stops.Length-1; i++)
            {
                Stops[i] = Stops[i + 1];
            }
        Array.Resize(ref Stops, Stops.Length - 1);
        }


        public IVehicle[] GetVehicles()
        {
            return Vehicles;
        }

#region IRoad Members
        

        /*public IStop[] GetStopArray(ICross roadedge) //начиная с этого перекрестка
        {
            if (roadedge == Cross1)
                return Stops;
            else
            {
                IStop[] temp = Stops;
                int min = 1000;
                int mink = -1;
                for (int i = 0; i < Stops.Length; i++)
                {
                        temp[i] = Stops[Stops.Length - i - 1];
                }
                return temp;
            } 
        }*/

        public IStop[] GetStopArray(ICross roadedge)
        {
            IStop[] temp = new Stop[Stops.Length];
            if (roadedge == Cross1)
            {
                float min = 1000;
                int mink = -1;
                for (int i = 0; i < Stops.Length; i++)
                {
                    min = 1000;
                    mink = -1;
                    int j = 0;
                    for (j = 0; j < Stops.Length; j++)
                    {
                        if (Stops[j]!=null)
                            if (Stops[j].Flag != 1)
                        if (Stops[j].Distance < min)
                        {
                            min = Stops[j].Distance;
                            mink = j;
                        }

                    }
                    if (mink != -1)
                    {
                        temp[i] = Stops[mink];
                        Stops[mink].Flag = 1;
                    }
                }
                for (int i = 0; i < Stops.Length; i++)
                {
                    temp[i].Flag = 0;
                }
            }
            else
            {
                float min = 1000;
                int mink = -1;
                for (int i = 0; i < Stops.Length; i++)
                {
                    min = 1000;
                    mink = -1;
                    int j = 0;
                    for (j = 0; j < Stops.Length; j++)
                    {
                        if (Stops[j] != null) 
                            if (Stops[j].Flag != 1)
                        if (this.Length - Stops[j].Distance < min)
                        {
                            
                            min = Stops[j].Distance;
                            mink = j;
                        }

                    }
                    if (mink != -1)
                    {
                        temp[i] = Stops[mink];
                        Stops[mink].Flag = 1;
                    }
                }
                for (int i = 0; i < Stops.Length; i++)
                {
                    temp[i].Flag = 0;
                }
            }
            Stops = temp;
            return temp;

 
        }

        public float GetStopDistance(ICross roadedge, IStop stop)
        {
            if (roadedge == Cross1) return stop.Distance;
            else return Length - stop.Distance;
        }

        public float GetLength()
        {
            return Length;
        }

        private void ModifySpeed(IVehicle taxi)
        {
            taxi.CurrentSpeed = (int)(taxi.MaxSpeed*SpeedModifier);
        }

        private void ModifyDurabilityDecreaseRate(IVehicle taxi)
        {
            taxi.CurrentDamageRate = (int)(taxi.DamageRate * DurabilityDecreaseModifier);
        }

        private void ModifyFuelDecreaseRate(IVehicle taxi)
        {
            taxi.CurrentFuelConsumingRate = (int)(taxi.FuelConsumingRate * FuelDecreaseModifier);
        }

        public void ModifyTaxiProperties(IVehicle taxi)
        {
            ModifyDurabilityDecreaseRate(taxi);
            ModifyFuelDecreaseRate(taxi);
            ModifySpeed(taxi);
        }

       

        public void AddTaxi(IVehicle taxi)
        {
            Array.Resize(ref Vehicles, Vehicles.Length + 1);
            Vehicles[Vehicles.Length - 1] = taxi;
        }

        public void DelTaxi(IVehicle taxi)
        {
            int k = 0;
            bool found = false;
            while ((k < Vehicles.Length) && (!found))
            {
                if (Vehicles[k] == taxi)
                {
                    found = true;
                }
                else
                {
                    k++;
                }
            }
            if (found)
            {
                Vehicles[k] = Vehicles[Vehicles.Length - 1];
                Array.Resize(ref Vehicles, Vehicles.Length - 1);
            }
        }
    
        public ICross GetFirstCross()
        {
            return Cross1;
        }

        public ICross GetCrossNotThis(ICross cross)
        {
            return (Cross1 == cross)? Cross2: Cross1;
        }

        public ICross GetSecondCross()
        {
            return Cross2;
        }

        #endregion

        #region IRoad Members


        public void SetStops(IStop[] stops)
        {
            Stops = stops;
        }

        #endregion

        #region IRoad Members


        public float DirectionX
        {
           get {return directionX;}
            set {directionX = value;}
        }

        public float DirectionY
        {
            get { return directionY; }
            set { directionY = value; }
        }
        public float SPEEDModifier
        {
            get { return SpeedModifier; }
            set { SpeedModifier = value; }
        }

        #endregion

        #region IRoad Members


        public string Name
        {
            get
            {
                return name; 
            }
            set
            {
                name = value;
            }
        }

        #endregion

        #region IRoad Members


        public void Reconstr()
        {
            Length = (float)Math.Sqrt((Cross1.GetPositionX() - Cross2.GetPositionX()) *
                                (Cross1.GetPositionX() - Cross2.GetPositionX()) +
                                (Cross1.GetPositionY() - Cross2.GetPositionY()) *
                                (Cross1.GetPositionY() - Cross2.GetPositionY()));
            directionX = (Cross2.GetPositionX() - Cross1.GetPositionX()) / Length;
            directionY = (Cross2.GetPositionY() - Cross1.GetPositionY()) / Length;
            
        }

        #endregion

        #region IRoad Members


        public bool Chosen
        {
            get
            {
                return chosen;
            }
            set
            {
                chosen = value;
            }
        }

        public bool Chosenchosen
        {
            get { return chosenchosen; }
            set { chosenchosen = value; }
        }

        #endregion
    }
}
